package com.example.demo.tools;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * CommonAsynThread：封装异步通用公共类
 * 
 * @author 
 *
 * @param <R>
 */
public class CommonAsynThread<R extends Object> {

	private ExecutorService executor;
	
	private CompletionService a;

	/**
	 * @使用案例 new
	 *       CommonCallableFuture<List<Integer>>(executor).createCallableFuture(()->intList.add(9));
	 * @传入要执行的方法即可：例如:()->intList.add(9)
	 * @param params
	 * @throws ExecutionException
	 * @throws InterruptedException
	 */
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		test(null);
	}

	public static void test(Map<String, Object> params) throws InterruptedException, ExecutionException {
		ExecutorService executor = Executors.newCachedThreadPool();
		List<Integer> intList = new ArrayList<Integer>();
		List<Integer> intList2 = new ArrayList<Integer>();
		Future<List<Integer>> future = new CommonAsynThread<List<Integer>>(executor).createCallableFuture(() -> {
			intList.add(9);
			intList.add(7);
			intList.add(5);
			intList.add(3);
			return intList;
		});
		if (null != future.get()) {
			System.out.println(intList.get(0));
			intList2 = (List<Integer>) future.get();
		}
		System.out.println(intList2.get(0));
		executor.shutdown();
	}

	public CommonAsynThread() {
		super();
	}

	public CommonAsynThread(ExecutorService executor) {
		super();
		this.executor = executor;
	}

	public ExecutorService getExecutor() {
		return executor;
	}

	public void setExecutor(ExecutorService executor) {
		this.executor = executor;
	}

	/**
	 * createCallableFuture:没有返回值的异步方法
	 * 
	 * @param jobTaskFuntion
	 * @return
	 * @throws InterruptedException
	 * @throws ExecutionException
	 */

	public void createRunnable(JobExeTaskFuntion jobTaskFuntion)  {
		this.getExecutor().submit(new UserRunnable(jobTaskFuntion));
	}

	/**
	 * createCallableFuture:有返回值的异步方法
	 * 
	 * @param jobTaskFuntion
	 * @return
	 * @throws InterruptedException
	 * @throws ExecutionException
	 */

	public Future<R> createCallableFuture(JobFutureTaskFuntion jobTaskFuntion) throws InterruptedException, ExecutionException {
		Future<R> future = this.getExecutor().submit(new UserCallable(jobTaskFuntion));
		return future;

	}

	/**
	 * UserRunnable:无返回值的线程
	 * 
	 * @author 
	 *
	 */
	class UserRunnable implements Runnable {
		private JobExeTaskFuntion jobFuntion;

		public JobExeTaskFuntion getJobFuntion() {
			return jobFuntion;
		}

		public void setJobFuntion(JobExeTaskFuntion jobFuntion) {
			this.jobFuntion = jobFuntion;
		}

		public UserRunnable(JobExeTaskFuntion jobFuntion) {
			super();
			this.jobFuntion = jobFuntion;
		}

		@Override
		public void run() {
			jobFuntion.execute();
		}
	}

	/**
	 * UserCallable:有返回值的线程
	 * 
	 * @author 
	 *
	 */
	class UserCallable implements Callable<R> {
		private JobFutureTaskFuntion jobTaskFuntion;

		public JobFutureTaskFuntion getJobTaskFuntion() {
			return jobTaskFuntion;
		}

		public void setJobTaskFuntion(JobFutureTaskFuntion jobTaskFuntion) {
			this.jobTaskFuntion = jobTaskFuntion;
		}

		public UserCallable(JobFutureTaskFuntion jobTaskFuntion) {
			super();
			this.jobTaskFuntion = jobTaskFuntion;
		}

		@Override
		@SuppressWarnings("unchecked")
		public R call() throws Exception {
			return (R) jobTaskFuntion.execute();
		}
	}

	/**
	 * JobExeFuntion：无返回值
	 * 
	 * @author
	 *
	 */
	@FunctionalInterface
	public interface JobExeTaskFuntion {
		void execute();
	}

	/**
	 * JobTaskFuntion:有返回值
	 * 
	 * @author
	 *
	 */
	@FunctionalInterface
	public interface JobFutureTaskFuntion {
		Object execute();
	}

}
